<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head>
  
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">

  
  <link href="../css/style.css" rel="stylesheet" type="text/css">

</head>
<body>
<h1>4.7. Умножение и деление</h1>
<p class="article">
Умножение и деление выполняются по-разному для чисел со знаком и без, поэтому в системе команд процессора x86 есть отдельные команды умножения и деления для чисел со знаком и для чисел без знака.
</p>
<h2>Умножение чисел без знака</h2>
<p class="article">
Для умножения чисел без знака предназначена команда MUL. У этой команды только один операнд — второй множитель, который должен находиться в регистре или в памяти. Местоположение первого множителя и результата задаётся неявно и зависит от размера операнда:
</p>
<table>
	<tr><td>Размер операнда</td><td>Множитель</td><td>Результат</td></tr>
	<tr><td>Байт</td><td>AL</td><td>AX</td></tr>
	<tr><td>Слово</td><td>AX</td><td>DX:AX</td></tr>
</table>
<p class="article">
Отличие умножения от сложения и вычитания в том, что разрядность результата получается в 2 раза больше, чем разрядность сомножителей. Также и в десятичной системе — например, умножая двухзначное число на двухзначное, мы можем получить в результате максимум четырёхзначное. Запись «DX:AX» означает, что старшее слово результата будет находиться в DX, а младшее — в AX. Примеры:
</p>
<pre class="code">
    mul bl    ;AX = AL * BL
    mul ax    ;DX:AX = AX * AX
</pre>
<p class="article">
Если старшая часть результата равна нулю, то флаги CF и ОF будут иметь нулевое значение. В этом случае старшую часть результата можно отбросить. Это свойство можно использовать в программе, если результат должен быть такого же размера, как множители.
</p>
<h2>Умножение чисел со знаком</h2>
<p class="article">
Для умножения чисел со знаком предназначена команда IMUL. Эта команда имеет три формы, различающиеся количеством операндов:
</p>
<ul>
	<li class="article list">С одним операндом — форма, аналогичная команде MUL. В качестве операнда указывается множитель. Местоположение другого множителя и результата определяется по таблице.
	</li>
	<li class="article list">С двумя операндами — указываются два множителя. Результат записывается на место первого множителя. Старшая часть результата в этом случае игнорируется. Кстати, эта форма команды не работает с операндами размером 1 байт.
	</li>
	<li class="article list">С тремя операндами — указывается положение результата, первого и второго множителя. Второй множитель должен быть непосредственным значением. Результат имеет такой же размер, как первый множитель, старшая часть результата игнорируется. Это форма тоже не работает с однобайтными множителями.
	</li>
</ul>
<p class="article">
Пример:
</p>
<pre class="code">
    imul cl           ;AX = AL * CL
    imul si           ;DX:AX = AX * SI
    imul bx,ax        ;BX = BX * AX
    imul cx,-5        ;CX = CX * (-5)
    imul dx,bx,134h   ;DX = BX * 134h
</pre>
<p class="article">
CF = OF = 0, если произведение помещается в младшей половине результата, иначе CF = OF = 1. Для второй и третьей формы команды CF = OF = 1 означает, что произошло переполнение.
</p>
<h2>Деление чисел без знака</h2>
<p class="article">
Деление целых двоичных чисел — это всегда деление с остатком! По аналогии с умножением, размер делителя, частного и остатка должен быть в 2 раза меньше размера делимого. Деление чисел без знака осуществляется с помощью команды DIV. У этой команды один операнд — делитель, который должен находиться в регистре или в памяти. Местоположение делимого, частного и остатка задаётся неявно и зависит от размера операнда:
</p>
<table>
	<tr><td>Размер операнда</td><td>Множитель</td><td>Результат</td></tr>
	<tr><td>Байт</td><td>AX</td><td>AL</td></tr>
	<tr><td>Слово</td><td>DX:AX</td><td>AX</td></tr>
</table>
<p class="article">
При выполнении команды DIV может возникнуть прерывание (о прерываниях я подробно расскажу потом, пока старайтесь избегать таких случаев):
</p>
<ul>
	<li class="article list">если делитель равен нулю;</li>
	<li class="article list">если частное не помещается в отведённую под него разрядную сетку (например, если при делении слова на байт частное больше 255).
	</li>
</ul>
<div class="notewarning">
При делении на ноль возникает ошбка времени исполнения. Надо проверять делитель на ноль!
</div>
<p class="article">
Пример:
</p>
<pre class="code">
    div cl   ;AL = AX / CL, остаток в AH
    div di   ;AX = DX:AX / DI, остаток в DX
</pre>
<h2>Деление чисел со знаком</h2>
<p class="article">
Для деления чисел со знаком предназначена команда IDIV. Единственным операндом является делитель. Местоположение делимого и частного определяется также, как для команды DIV. Эта команда тоже генерирует прерывание при делении на ноль или слишком большом частном.
</p>

</body>
</html>
